﻿using Moq;
using NUnit.Framework;
using SportsStore.Repository.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SportsStore.ProductService;
using SportsStore.Model;
using SportsStore.ServicesInterfaces;
using SportsStore.ServicesInterfaces.Interfaces;

namespace SportsStore.UnitTests.Services
{
  [TestFixture]
  public class ProductServiceTest
  {
    [SetUp]
    public void Setup()
    {
      _productRepository = new Mock<IProductRepository>();
      _productService = new SportsStore.ProductService.ProductService(_productRepository.Object);
    }

    private IProductService _productService;
    private Mock<IProductRepository> _productRepository;
    private const string _name = "name";

    [Test]
    public void GivenValidData_WhenIAskForOrderProducts_AndTheDataBaseIsNotAvailable_ThenASportsStoreExceptionIsThrown()
    {
      _productRepository.Setup(p => p.GetProducts(It.IsAny<int>(), It.IsAny<int>(), It.IsAny<string>()))
                        .Throws<Exception>();
      Assert.Throws<SportsStoreException>(() => _productService.GetProducts(1, 1, null));
    }

    [Test]
    public void GivenValidData_WhenIAskForOrderProducts_ThenTheProductsAreReturned()
    {
      _productRepository.Setup(p => p.GetProducts(1, 1, null))
                        .Returns(new PagedResult<Product> { Results = new List<Product>() });
      PagedResult<Product> products = _productService.GetProducts(1, 1, null);
      Assert.That(products.Results.Count, Is.EqualTo(0));
    }

    [Test]
    public void GivenAReuqestForLessThatAPageOfProducts_AndItsTheFirstPage_ThenTheProductIsReturned()
    {
      _productRepository.Setup(p => p.GetProducts(1, 1, null))
                        .Returns(new PagedResult<Product> { Results = new List<Product>() });
      _productService.GetProducts(1, 1, null);

      _productRepository.Verify(p => p.GetProducts(1, 1, null), Times.Once());
    }

    [Test]
    public void GivenAValidId_WhenAProductIsRequested_ThenTheProductIsReturned()
    {
      _productRepository.Setup(u => u.GetProduct(1)).Returns(new Product() { Name = _name });
      Product product = _productService.GetProduct(1);
      Assert.That(product, Is.Not.Null);
      Assert.That(product.Name, Is.EqualTo(_name));
    }
  }
}
